package com.ml.loan.common.exception;

import com.google.common.collect.Maps;
import com.ml.loan.common.model.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import javax.validation.ConstraintViolationException;
import java.sql.SQLException;
import java.util.Map;

/**
 * 统一异常处理
 *
 * @author Mickey
 * @date 2022/2/15 18:13
 */
@Slf4j
@RestControllerAdvice
public class BusinessExceptionAdvice {

    /**
     * 通用业务异常
     *
     * @param exception
     * @return com.zsk.loaned.common.model.R
     * @Author Mickey
     * @Date 2021/2/11 0:05
     **/
    @ExceptionHandler(value = BusinessException.class)
    public JsonResult handlerBusinessException(BusinessException exception) {
        return JsonResult.error(exception.getCode(), exception.getMessage());
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public JsonResult handlerMethodArgumentNotValidExcetion(MethodArgumentNotValidException exception) {
        Map<String, String> map = Maps.newHashMap();
        BindingResult bindingResult = exception.getBindingResult();
        bindingResult.getFieldErrors().forEach(fieldError -> {
            String message = fieldError.getDefaultMessage();
            String field = fieldError.getField();
            map.put(field, message);
        });
        return JsonResult.error("参数错误").setData(map);
    }

    @ExceptionHandler(value = BindException.class)
    public JsonResult handlerBindException(BindException exception) {
        Map<String, String> map = Maps.newHashMap();
        BindingResult bindingResult = exception.getBindingResult();
        bindingResult.getFieldErrors().forEach(fieldError -> {
            String message = fieldError.getDefaultMessage();
            String field = fieldError.getField();
            map.put(field, message);
        });
        return JsonResult.error("参数错误").setData(map);
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    public JsonResult constraintViolationException(ConstraintViolationException exception) {
        Map<String, String> map = Maps.newHashMap();
        String[] msgList = exception.getMessage().split(", ");
        for (String msg : msgList) {
            String[] fieldError = msg.split(": ");
            String key = fieldError[0].split("\\.")[1];
            String message = fieldError[1];
            map.put(key, message);
        }
        return JsonResult.error("参数错误").setData(map);
    }


    @ExceptionHandler(value = UnauthorizedException.class)
    public JsonResult handlerUnauthorizedException(UnauthorizedException exception) {
        return JsonResult.error(403, "没有访问权限");
    }

    @ExceptionHandler(value = MaxUploadSizeExceededException.class)
    public JsonResult handlerBusinessException(MaxUploadSizeExceededException exception) {
        return JsonResult.error("文件上传过大");
    }


    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public JsonResult handlerBusinessException(HttpRequestMethodNotSupportedException exception) {
        return JsonResult.error("该方法不支持" + exception.getMethod());
    }

    @ExceptionHandler(value = HttpMediaTypeNotSupportedException.class)
    public JsonResult handlerBusinessException(HttpMediaTypeNotSupportedException exception) {
        return JsonResult.error("不支持该媒体类型");
    }

    @ExceptionHandler({SQLException.class})
    public JsonResult handleSQLException(SQLException e) {
        log.error("服务运行SQLException异常", e);
        return JsonResult.error("服务运行SQLException异常");
    }

    @ExceptionHandler(value = IllegalArgumentException.class)
    public JsonResult badArgumentRequestException(IllegalArgumentException e) {
        log.error("参数解析失败", e);
        return JsonResult.error("参数解析失败");
    }

    @ExceptionHandler(value = Exception.class)
    public JsonResult handleException(Exception e) {
        log.error("系统异常{}", e.getMessage(), e);
        return JsonResult.error("Sorry，服务器开小差啦~").setData(e.getMessage());
    }

}
